package com.xingkeduo.business.transformation.json;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.xingkeduo.pojo.query.JobseekerAssessRateQO;
import com.xingkeduo.pojo.query.JobseekerAssessRateQO.ScoreEnums;
import com.xingkeduo.pojo.table.JobseekerAssessRateTO;
import com.xingkeduo.pojo.table.JobseekerAssessRateTO.Type;
import com.xingkeduo.util.pojo.base.BaseJson;
import com.xingkeduo.util.pojo.enums.YesNoEnum;
import com.xingkeduo.util.pojo.exception.InputParamException;
import com.xingkeduo.util.tool.CommonUtil;
import com.xingkeduo.util.tool.RegularUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * 求职者考核结果封装类
 *
 * @author 高杰
 * @time 2018年12月25日 下午1:45:17
 * @description
 */
@Component
public class JobseekerAssessRateJTO extends BaseJson {
    public static List<JobseekerAssessRateTO> createTablesForNew(String json)
            throws Throwable {
        JsonNode root = validJson(json);
        if (root == null)
            throw new InputParamException(InputParamException.Type.INVALID, "参数");

        if (!root.has("rates"))
            throw new InputParamException(InputParamException.Type.NULL, "评分");
        if (!root.path("rates").isArray())
            throw new InputParamException(InputParamException.Type.INVALID, "评分");
        List<JobseekerAssessRateTO> rates = new ArrayList<>();
        for (Iterator<JsonNode> iterator = root.path("rates").elements(); iterator.hasNext(); ) {
            JsonNode node = iterator.next();
            rates.add(createTableForNew(node));
        }

        return rates;
    }

    public static JobseekerAssessRateTO createTableForNew(JsonNode root) throws Throwable {
        return new JobseekerAssessRateTO().setType(validType(root, YesNoEnum.YES))
                .setScore(validScore(root, YesNoEnum.YES));
    }

    public static JobseekerAssessRateQO createQueryForTypes(String json) throws Throwable {
        JobseekerAssessRateQO query = new JobseekerAssessRateQO();
        JsonNode root = validJson(json);
        if (root == null)
            return query;

        Set<Integer> typeSet = new HashSet<>(10);
        Set<Integer> scoreSet = new HashSet<>(10);
        if (root.has("firstScore")) {
            scoreSet.addAll(getScores("firstScore", root, typeSet));
            query.setFirstNum(validFirstScore(root, YesNoEnum.NO));
        }
        if (root.has("techScore")) {
            scoreSet.addAll(getScores("techScore", root, typeSet));
            query.setTechNum(validTechScores(root, YesNoEnum.NO));
        }
        if (root.has("attainScore")) {
            scoreSet.addAll(getScores("attainScore", root, typeSet));
            query.setAttAinNum(validAttainScores(root, YesNoEnum.NO));
        }
        if (scoreSet.size() == 0) {
            initSetValue(scoreSet);
        }
        query.setTypeSet(typeSet).setScoreList(scoreSet);
        return query;
    }


    public static ObjectNode toJson(JobseekerAssessRateTO table) {
        ObjectNode root = MAPPER.createObjectNode();

        if (table != null) {
            if (table.getType() != null) {
                root.put("type_value", table.getType().getValue());
                root.put("type_desc", table.getType().getDesc());
            }
            if (table.getScore() > 0)
                root.put("score", table.getScore());
            if (table.getJobseekerAssessId() > 0)
                root.put("jobseekerassessid", table.getJobseekerAssessId());

            toBaseJson(root, table);
        }

        return root;
    }

    public static ArrayNode toJson(List<JobseekerAssessRateTO> tables) {
        ArrayNode root = MAPPER.createArrayNode();

        if (!CommonUtil.isEmpty(tables))
            for (Iterator<JobseekerAssessRateTO> iterator = tables.iterator(); iterator.hasNext(); ) {
                root.add(toJson(iterator.next()));
            }

        return root;
    }

    public static int validScore(JsonNode node, YesNoEnum isRequired) throws Throwable {
        String key = "score";
        if (YesNoEnum.YES == isRequired && !node.has(key))
            throw new InputParamException(InputParamException.Type.NULL, key);

        if (node.has(key)) {
            String value = node.path(key).asText().trim();
            if (!RegularUtil.isPositiveInteger(value) || Integer.parseInt(value) > 5)
                throw new InputParamException(InputParamException.Type.INVALID, key + " error");
            return Integer.parseInt(value);
        }
        return 0;
    }

    public static Type validType(JsonNode node, YesNoEnum isRequired) throws Throwable {
        String key = "type";
        if (YesNoEnum.YES == isRequired && !node.has(key))
            throw new InputParamException(InputParamException.Type.NULL, key);

        if (node.has(key)) {
            String value = node.path(key).asText().trim();
            if (!Type.validValue(value))
                throw new InputParamException(InputParamException.Type.INVALID, key + " error");
            return Type.getType(value);
        }
        return null;
    }

    public static List<Integer> validFirstScore(JsonNode node, YesNoEnum isRequired) throws Throwable {
        String key = "firstScore";
        if (YesNoEnum.YES == isRequired && !node.has(key))
            throw new InputParamException(InputParamException.Type.NULL, key);
        List<Integer> firstList = new ArrayList<>(8);
        if (node.has(key)) {
            String value = node.path(key).asText().trim();
            String[] scores = value.split(",");

            if (scores.length > 0 && !"".equals(scores[0])) {
                for (String str : scores) {
                    firstList.add(ScoreEnums.getValue(str));
                }
                return firstList;
            }
        }
        initScoreList(firstList);
        return firstList;
    }

    public static List<Integer> validTechScores(JsonNode node, YesNoEnum isRequired) throws Throwable {
        String key = "techScore";
        if (YesNoEnum.YES == isRequired && !node.has(key))
            throw new InputParamException(InputParamException.Type.NULL, key);

        List<Integer> firstList = new ArrayList<>(8);
        if (node.has(key)) {
            String value = node.path(key).asText().trim();
            String[] scores = value.split(",");

            if (scores.length > 0 && !"".equals(scores[0])) {
                for (String str : scores) {
                    firstList.add(ScoreEnums.getValue(str));
                }
                return firstList;
            }
        }
        initScoreList(firstList);
        return firstList;
    }

    public static List<Integer> validAttainScores(JsonNode node, YesNoEnum isRequired) throws Throwable {
        String key = "attainScore";
        if (YesNoEnum.YES == isRequired && !node.has(key))
            throw new InputParamException(InputParamException.Type.NULL, key);

        List<Integer> firstList = new ArrayList<>(8);
        if (node.has(key)) {
            String value = node.path(key).asText().trim();
            String[] scores = value.split(",");

            if (scores.length > 0 && !"".equals(scores[0])) {
                for (String str : scores) {
                    firstList.add(ScoreEnums.getValue(str));
                }
                return firstList;
            }
        }
        initScoreList(firstList);
        return firstList;
    }

    private static Set<Integer> getScores(String key, JsonNode node, Set<Integer> typeSet) {
        if (node.has(key)) {
            Set<Integer> scroesSet = new HashSet<>(10);
            String value = node.path(key).asText().trim();
            if (StringUtils.isBlank(value)) {
                return scroesSet;
            }
            switch (key) {
                case "firstScore":
                    typeSet.add(1);
                    break;
                case "techScore":
                    typeSet.add(2);
                    break;
                case "attainScore":
                    typeSet.add(3);
                    break;
                default:
            }
            String[] scores = value.split(",");
            for (int i = 0, j = scores.length; i < j; i++) {
                scroesSet.add(ScoreEnums.getValue(scores[i]));
            }
            return scroesSet;
        }
        return null;
    }

    private static void initSetValue(Set<Integer> scroesSet) {
        scroesSet.add(1);
        scroesSet.add(2);
        scroesSet.add(3);
        scroesSet.add(4);
        scroesSet.add(5);
    }

    private static void initScoreList(List<Integer> scoreList) {
        scoreList.add(1);
        scoreList.add(2);
        scoreList.add(3);
        scoreList.add(4);
        scoreList.add(5);
    }
}
